#!/bin/bash

# Provide source directive to shellcheck.
# shellcheck source=meta-facebook/meta-yosemite4/recipes-phosphor/state/phosphor-state-manager/power-cmd
source /usr/libexec/phosphor-state-manager/power-cmd
CHASSIS_ID=$1
slot_power_control_lock="/run/slot_power_control_${CHASSIS_ID}.lock"
CHASSIS_BUS=$(($1 - 1))
IO_EXP_P0_PWRGD_R_OUT=18
GPIOCHIP_IO_EXP_HOST_POWER_STATUS=$(basename "/sys/bus/i2c/devices/$CHASSIS_BUS-0023/"*gpiochip*)

get_host_status() {
    host_status=$(gpio_get "$GPIOCHIP_IO_EXP_HOST_POWER_STATUS" "$IO_EXP_P0_PWRGD_R_OUT")

    if [ "$host_status" = "gpioget failed" ]; then
        echo "Failed to get host status"
        exit 1
    fi
}

msg="Execute host$1 DC power on"
echo "${msg}"
add_sel "${msg}" "Info"

exec 300>"$slot_power_control_lock"
if ! flock -n 300 ; then
    msg="Wait power control flock release for host$CHASSIS_ID DC on"
    echo "${msg}"
    add_sel "${msg}" "Info"
fi
flock -x 300
trap 'flock -u 300' EXIT

get_host_status

if [ "$host_status" == "$STATE_ON" ]
then
    echo "Already host$1 DC power on."
    exit 0;
fi

# Check if PRSNT_SB_SLOT{1~8}_N is exist, if not exist, continues power-on process
if [ ! -f "/tmp/gpio/PRSNT_SB_SLOT${1}_N" ]; then
    echo "PRSNT_SB_SLOT${1}_N is not exist, continue power-on process"
else
    slot_presence=$(cat /tmp/gpio/PRSNT_SB_SLOT"${1}"_N)
    if [ "$slot_presence" -ne 0 ]; then
        echo "Host$1 is not present, skip power-on process"
        exit 1
    fi
fi

EID=$(($1*10))
MAX_RETRY=12
count=0

while [ $count -lt $MAX_RETRY ]; do
    # Set state effecter state: Entity ID 0x0000 for host power control, 0x1 for power on
    resp=$(pldmtool raw -d 0x80 0x02 0x39 0x00 0x00 0x01 0x00 0x01 -m "$EID" | grep "39 00 $")
    # check BIC response with success return code
    if [ -n "$resp" ]; then
        echo "Host$1 send power on command to bic success"
        break;
    else
        echo "Waiting EID $EID $count"
    fi
    sleep 5;
    count=$((count + 1))
done

# Host power ON will trigger the BIC to configure the server board CPLD register and set the power sequence.
# Power Sequence:
#   - Set PLAT_PLDM_HOST_PWR_CTRL_DEFAULT to 0xFF
#   - Set PLAT_PLDM_HOST_PWR_BTN_LOW to 0xFE
#   - Sleep for 1 second
#   - Set PLAT_PLDM_HOST_PWR_CTRL_DEFAULT back to 0xFF

# Wait for the host to power on
sleep 2s

get_host_status

if [ "$host_status" == "$STATE_ON" ]
then
    echo "Host$1 DC power on success"
    msg="Host$1 system DC power is on"
    echo "${msg}"
    add_sel "${msg}" "Info"
    exit 0;
else
    msg="Failed to set host$1 DC power on"
    echo "${msg}"
    add_sel "${msg}" "Error"
    exit 1
fi
